package com.xyht.sca_s.student_manage_system.modules.enrollmentManagement.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.modules.enrollmentManagement.entity.SmsEnrollmentManagementStudentInfo;
import com.xyht.sca_s.student_manage_system.modules.enrollmentManagement.entity.SmsEnrollmentManagementTask;
import com.xyht.sca_s.student_manage_system.modules.enrollmentManagement.entity.resp.*;
import com.xyht.sca_s.student_manage_system.modules.enrollmentManagement.mapper.SmsEnrollmentManagementStudentInfoMapper;
import com.xyht.sca_s.student_manage_system.modules.enrollmentManagement.mapper.SmsEnrollmentManagementTaskMapper;
import com.xyht.sca_s.student_manage_system.modules.enrollmentManagement.service.SmsEnrollmentManagementStudentDataStatisticsService;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgStructure;
import com.xyht.sca_s.student_manage_system.modules.org.mapper.SmsOrgStructureMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.dormitory.constant.OrgLevelConstant.COLLEGE_LEVEL;
import static com.xyht.sca_s.student_manage_system.modules.dormitory.constant.OrgLevelConstant.COLLEGE_PARENT_ID;
import static com.xyht.sca_s.student_manage_system.modules.enrollmentManagement.constant.IsCancelStatusConstant.IS_CANCEL_STATUS_FALSE;

/**
 * <p>
 * 招生管理学生信息 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2024-01-15
 */
@Service
public class SmsEnrollmentManagementStudentDataStatisticsServiceImpl implements SmsEnrollmentManagementStudentDataStatisticsService {
    @Resource
    private SmsEnrollmentManagementStudentInfoMapper smsEnrollmentManagementStudentInfoMapper;
    @Resource
    private SmsEnrollmentManagementTaskMapper smsEnrollmentManagementTaskMapper;
    @Resource
    private SmsOrgStructureMapper smsOrgStructureMapper;

    @Override
    public ResponseResult getMajorDataStatistics(String taskId, String collegeId, String majorId, Integer pageNum, Integer pageSize) {
        List<SmsStudentDataStatisticsMajorResp> majorList = new ArrayList<>();

        Page<Map<String, Object>> page = new Page<>(pageNum,pageSize);
        QueryWrapper<SmsEnrollmentManagementStudentInfo> studentInfoLambdaQueryWrapper = new QueryWrapper<>();
        if (!isNullOrEmpty(collegeId)) {
            studentInfoLambdaQueryWrapper.lambda().eq(SmsEnrollmentManagementStudentInfo::getCollegeId,collegeId);
        }
        if (!isNullOrEmpty(majorId)) {
            studentInfoLambdaQueryWrapper.lambda().eq(SmsEnrollmentManagementStudentInfo::getMajorId,majorId);
        }
        smsEnrollmentManagementStudentInfoMapper.selectMapsPage(page,studentInfoLambdaQueryWrapper
                .select("count(major_name) as majorNum,college_name as collegeName,major_name as majorName")
                .lambda()
                .eq(SmsEnrollmentManagementStudentInfo::getEnrollmentTaskId,isNullOrEmpty(taskId) ? "" : taskId)
                .eq(SmsEnrollmentManagementStudentInfo::getIsCancel,IS_CANCEL_STATUS_FALSE)
                .groupBy(SmsEnrollmentManagementStudentInfo::getCollegeName)
                .groupBy(SmsEnrollmentManagementStudentInfo::getMajorName)
                .orderByDesc(SmsEnrollmentManagementStudentInfo::getMajorName));

        List<Map<String, Object>> mapList = page.getRecords();
        if (mapList.isEmpty()) {
            return CommonResult.success(majorList);
        }
        for (Map<String, Object> map : mapList) {
            SmsStudentDataStatisticsMajorResp smsStudentDataStatisticsMajorResp = JSONObject.parseObject(JSON.toJSONString(map), SmsStudentDataStatisticsMajorResp.class);
            if (isNullOrEmpty(smsStudentDataStatisticsMajorResp)) {
                continue;
            }
            SmsStudentDataStatisticsMajorResp studentDataStatisticsMajorResp = new SmsStudentDataStatisticsMajorResp();
            studentDataStatisticsMajorResp.setCollegeName(smsStudentDataStatisticsMajorResp.getCollegeName());
            studentDataStatisticsMajorResp.setMajorName(smsStudentDataStatisticsMajorResp.getMajorName());
            studentDataStatisticsMajorResp.setMajorNum(smsStudentDataStatisticsMajorResp.getMajorNum());
            majorList.add(studentDataStatisticsMajorResp);
        }
        return CommonResult.success(majorList,(int)page.getTotal());
    }

    @Override
    public ResponseResult getProvincesDataStatistics(String taskId, String collegeId, String majorId, String provinces, Integer pageNum, Integer pageSize) {
        List<SmsStudentDataStatisticsProvincesResp> provincesList = new ArrayList<>();
        Page<Map<String, Object>> page = new Page<>(pageNum,pageSize);
        QueryWrapper<SmsEnrollmentManagementStudentInfo> studentInfoLambdaQueryWrapper = new QueryWrapper<>();
        if (!isNullOrEmpty(collegeId)) {
            studentInfoLambdaQueryWrapper.lambda().eq(SmsEnrollmentManagementStudentInfo::getCollegeId,collegeId);
        }
        if (!isNullOrEmpty(majorId)) {
            studentInfoLambdaQueryWrapper.lambda().eq(SmsEnrollmentManagementStudentInfo::getMajorId,majorId);
        }
        if (!isNullOrEmpty(provinces)) {
            studentInfoLambdaQueryWrapper.lambda().like(SmsEnrollmentManagementStudentInfo::getStudentProvinces,provinces);
        }
        smsEnrollmentManagementStudentInfoMapper.selectMapsPage(page,studentInfoLambdaQueryWrapper
                .select("count(student_provinces) as provincesNum,college_name as collegeName,major_name as majorName,student_provinces as stuProvinces")
                .lambda()
                .isNotNull(SmsEnrollmentManagementStudentInfo::getStudentProvinces)
                .eq(SmsEnrollmentManagementStudentInfo::getEnrollmentTaskId,isNullOrEmpty(taskId) ? "" : taskId)
                .eq(SmsEnrollmentManagementStudentInfo::getIsCancel,IS_CANCEL_STATUS_FALSE)
                .groupBy(SmsEnrollmentManagementStudentInfo::getCollegeName)
                .groupBy(SmsEnrollmentManagementStudentInfo::getMajorName)
                .groupBy(SmsEnrollmentManagementStudentInfo::getStudentProvinces));

        List<Map<String, Object>> mapList = page.getRecords();
        if (mapList.isEmpty()) {
            return CommonResult.success(provincesList);
        }
        for (Map<String, Object> map : mapList) {
            SmsStudentDataStatisticsProvincesResp smsStudentDataStatisticsProvincesResp = JSONObject.parseObject(JSON.toJSONString(map), SmsStudentDataStatisticsProvincesResp.class);
            if (isNullOrEmpty(smsStudentDataStatisticsProvincesResp)) {
                continue;
            }
            SmsStudentDataStatisticsProvincesResp studentDataStatisticsProvincesResp = new SmsStudentDataStatisticsProvincesResp();
            studentDataStatisticsProvincesResp.setCollegeName(smsStudentDataStatisticsProvincesResp.getCollegeName());
            studentDataStatisticsProvincesResp.setMajorName(smsStudentDataStatisticsProvincesResp.getMajorName());
            studentDataStatisticsProvincesResp.setStuProvinces(smsStudentDataStatisticsProvincesResp.getStuProvinces());
            studentDataStatisticsProvincesResp.setProvincesNum(smsStudentDataStatisticsProvincesResp.getProvincesNum());
            provincesList.add(studentDataStatisticsProvincesResp);
        }
        return CommonResult.success(provincesList,(int)page.getTotal());
    }

    @Override
    public ResponseResult getSexDataStatistics(String taskId, String collegeId, String majorId, String sex, Integer pageNum, Integer pageSize) {
        List<SmsStudentDataStatisticsSexResp> sexList = new ArrayList<>();

        Page<Map<String, Object>> page = new Page<>(pageNum,pageSize);
        QueryWrapper<SmsEnrollmentManagementStudentInfo> studentInfoLambdaQueryWrapper = new QueryWrapper<>();
        if (!isNullOrEmpty(collegeId)) {
            studentInfoLambdaQueryWrapper.lambda().eq(SmsEnrollmentManagementStudentInfo::getCollegeId,collegeId);
        }
        if (!isNullOrEmpty(majorId)) {
            studentInfoLambdaQueryWrapper.lambda().eq(SmsEnrollmentManagementStudentInfo::getMajorId,majorId);
        }
        if (!isNullOrEmpty(sex)) {
            studentInfoLambdaQueryWrapper.lambda().eq(SmsEnrollmentManagementStudentInfo::getStudentSex,sex);
        }
        smsEnrollmentManagementStudentInfoMapper.selectMapsPage(page,studentInfoLambdaQueryWrapper
                .select("count(student_sex) as sexNum,college_name as collegeName,major_name as majorName,student_sex as stuSex")
                .lambda()
                .isNotNull(SmsEnrollmentManagementStudentInfo::getStudentSex)
                .eq(SmsEnrollmentManagementStudentInfo::getEnrollmentTaskId,isNullOrEmpty(taskId) ? "" : taskId)
                .eq(SmsEnrollmentManagementStudentInfo::getIsCancel,IS_CANCEL_STATUS_FALSE)
                .groupBy(SmsEnrollmentManagementStudentInfo::getCollegeName)
                .groupBy(SmsEnrollmentManagementStudentInfo::getMajorName)
                .groupBy(SmsEnrollmentManagementStudentInfo::getStudentSex));

        List<Map<String, Object>> mapList = page.getRecords();
        if (mapList.isEmpty()) {
            return CommonResult.success(sexList);
        }
        for (Map<String, Object> map : mapList) {
            SmsStudentDataStatisticsSexResp smsStudentDataStatisticsSexResp = JSONObject.parseObject(JSON.toJSONString(map), SmsStudentDataStatisticsSexResp.class);
            if (isNullOrEmpty(smsStudentDataStatisticsSexResp)) {
                continue;
            }
            SmsStudentDataStatisticsSexResp studentDataStatisticsSexResp = new SmsStudentDataStatisticsSexResp();
            studentDataStatisticsSexResp.setCollegeName(smsStudentDataStatisticsSexResp.getCollegeName());
            studentDataStatisticsSexResp.setMajorName(smsStudentDataStatisticsSexResp.getMajorName());
            studentDataStatisticsSexResp.setStuSex(smsStudentDataStatisticsSexResp.getStuSex());
            studentDataStatisticsSexResp.setSexNum(smsStudentDataStatisticsSexResp.getSexNum());
            sexList.add(studentDataStatisticsSexResp);
        }
        return CommonResult.success(sexList,(int)page.getTotal());
    }

    @Override
    public ResponseResult getBigDataPeopleStatistics(String taskId) {
        SmsStudentDataStatisticsBigDataPeopleResp peopleResp = new SmsStudentDataStatisticsBigDataPeopleResp();
        int taskNum = 0;
        int realNum = 0;
        int boyNum = 0;
        int girlNum = 0;
        int boyRatio = 0;
        int girlRatio = 0;
        if (isNullOrEmpty(taskId)) {
            peopleResp.setRealNum(realNum);
            peopleResp.setTaskNum(taskNum);
            peopleResp.setBoyNum(boyNum);
            peopleResp.setGirlNum(girlNum);
            peopleResp.setBoyRatio(boyRatio);
            peopleResp.setGirlRatio(girlRatio);
            return CommonResult.success(peopleResp);
        }

        SmsEnrollmentManagementTask smsEnrollmentManagementTask = smsEnrollmentManagementTaskMapper.selectById(taskId);
        if (isNullOrEmpty(smsEnrollmentManagementTask)) {
            return CommonResult.failed(CommonCodeEnum.ENROLLMENT_MANAGEMENT_TASK_NOT_EXIST);
        }
        //计划招生人数
        taskNum = smsEnrollmentManagementTask.getTaskNum();
        List<Map<String, Object>> mapList = smsEnrollmentManagementStudentInfoMapper.selectMaps(new QueryWrapper<SmsEnrollmentManagementStudentInfo>()
                .select("SUM(CASE WHEN student_sex = '女' THEN 1 ELSE 0 END) girlNum,SUM(CASE WHEN student_sex = '男' THEN 1 ELSE 0 END) boyNum")
                .lambda()
                .eq(SmsEnrollmentManagementStudentInfo::getEnrollmentTaskId, taskId)
                .eq(SmsEnrollmentManagementStudentInfo::getIsCancel, IS_CANCEL_STATUS_FALSE)
                .groupBy(SmsEnrollmentManagementStudentInfo::getStudentSex));
        if (mapList.isEmpty()) {
            peopleResp.setRealNum(realNum);
            peopleResp.setTaskNum(taskNum);
            peopleResp.setBoyNum(boyNum);
            peopleResp.setGirlNum(girlNum);
            peopleResp.setBoyRatio(boyRatio);
            peopleResp.setGirlRatio(girlRatio);
            return CommonResult.success(peopleResp);
        }
        for (Map<String, Object> map : mapList) {
            SmsStudentDataStatisticsBigDataPeopleResp bigDataPeopleResp = JSONObject.parseObject(JSON.toJSONString(map), SmsStudentDataStatisticsBigDataPeopleResp.class);
            if (isNullOrEmpty(bigDataPeopleResp)) {
                continue;
            }
            Integer girlNum1 = bigDataPeopleResp.getGirlNum();
            Integer boyNum1 = bigDataPeopleResp.getBoyNum();
            if (boyNum1 != 0) {
                boyNum = bigDataPeopleResp.getBoyNum();
            } else if (girlNum1 != 0) {
                girlNum = bigDataPeopleResp.getGirlNum();
            }
        }
        realNum = boyNum + girlNum;
        if (realNum != 0) {
            boyRatio = (int) Math.round((double) boyNum / realNum * 10);
            girlRatio = 10 - boyRatio;
        }
        peopleResp.setRealNum(realNum);
        peopleResp.setTaskNum(taskNum);
        peopleResp.setBoyNum(boyNum);
        peopleResp.setGirlNum(girlNum);
        peopleResp.setBoyRatio(boyRatio);
        peopleResp.setGirlRatio(girlRatio);
        return CommonResult.success(peopleResp);
    }

    @Override
    public ResponseResult getBigDataCollegeStatistics(String taskId, Integer pageNum, Integer pageSize) {
        Page<SmsOrgStructure> page = new Page<>(pageNum,pageSize);
        List<SmsStudentDataStatisticsBigDataCollegeResp> collegeList = new ArrayList<>();
        if (isNullOrEmpty(taskId)) {
            return CommonResult.success(collegeList);
        }
        smsOrgStructureMapper.selectPage(page,new LambdaQueryWrapper<SmsOrgStructure>()
                .eq(SmsOrgStructure::getParentId, COLLEGE_PARENT_ID)
                .eq(SmsOrgStructure::getLevel, COLLEGE_LEVEL));
        List<SmsOrgStructure> structureList = page.getRecords();
        if (structureList.isEmpty()) {
            return CommonResult.success(collegeList);
        }
        Integer sum = smsEnrollmentManagementStudentInfoMapper.selectCount(new LambdaQueryWrapper<SmsEnrollmentManagementStudentInfo>()
                .eq(SmsEnrollmentManagementStudentInfo::getEnrollmentTaskId, taskId)
                .eq(SmsEnrollmentManagementStudentInfo::getIsCancel, IS_CANCEL_STATUS_FALSE));
        for (SmsOrgStructure smsOrgStructure : structureList) {
            Integer collegeCount = smsEnrollmentManagementStudentInfoMapper.selectCount(new LambdaQueryWrapper<SmsEnrollmentManagementStudentInfo>()
                    .eq(SmsEnrollmentManagementStudentInfo::getEnrollmentTaskId, taskId)
                    .eq(SmsEnrollmentManagementStudentInfo::getIsCancel, IS_CANCEL_STATUS_FALSE)
                    .eq(SmsEnrollmentManagementStudentInfo::getCollegeName, smsOrgStructure.getOrgName()));
            SmsStudentDataStatisticsBigDataCollegeResp smsStudentDataStatisticsBigDataCollegeResp = new SmsStudentDataStatisticsBigDataCollegeResp();
            smsStudentDataStatisticsBigDataCollegeResp.setCollegeName(smsOrgStructure.getOrgName());
            int collegeNum = 0;
            int collegeRatio = 0;
            if (sum == 0) {
                smsStudentDataStatisticsBigDataCollegeResp.setCollegeNum(collegeNum);
            }else {
                smsStudentDataStatisticsBigDataCollegeResp.setCollegeNum(collegeCount);
                collegeRatio = (int)(double)collegeCount / sum * 100;
            }
            smsStudentDataStatisticsBigDataCollegeResp.setCollegeRatio(collegeRatio);
            collegeList.add(smsStudentDataStatisticsBigDataCollegeResp);
        }

        return CommonResult.success(collegeList,(int)page.getTotal());
    }

    @Override
    public ResponseResult getBigDataProvincesStatistics(String taskId, Integer pageNum, Integer pageSize) {
        List<SmsStudentDataStatisticsBigDataProvincesResp> provincesList = new ArrayList<>();
        Page<Map<String, Object>> page = new Page<>(pageNum,pageSize);
        if (isNullOrEmpty(taskId)) {
            return CommonResult.success(provincesList);
        }
        smsEnrollmentManagementStudentInfoMapper.selectMapsPage(page,new QueryWrapper<SmsEnrollmentManagementStudentInfo>()
                .select("SUM(CASE WHEN student_sex = '女' THEN 1 ELSE 0 END) girlNum,SUM(CASE WHEN student_sex = '男' THEN 1 ELSE 0 END) boyNum,student_provinces stuProvinces")
                .lambda()
                .eq(SmsEnrollmentManagementStudentInfo::getEnrollmentTaskId, taskId)
                .eq(SmsEnrollmentManagementStudentInfo::getIsCancel, IS_CANCEL_STATUS_FALSE)
                .groupBy(SmsEnrollmentManagementStudentInfo::getStudentProvinces));
        List<Map<String, Object>> mapList = page.getRecords();
        if (mapList.isEmpty()) {
            return CommonResult.success(provincesList);
        }
        for (Map<String, Object> map : mapList) {
            SmsStudentDataStatisticsBigDataProvincesResp smsStudentDataStatisticsBigDataProvincesResp = JSONObject.parseObject(JSON.toJSONString(map), SmsStudentDataStatisticsBigDataProvincesResp.class);
            if (isNullOrEmpty(smsStudentDataStatisticsBigDataProvincesResp)) {
                continue;
            }
            Integer boyNum = smsStudentDataStatisticsBigDataProvincesResp.getBoyNum();
            Integer girlNum = smsStudentDataStatisticsBigDataProvincesResp.getGirlNum();
            int provincesNum = boyNum + girlNum;
            SmsStudentDataStatisticsBigDataProvincesResp studentDataStatisticsBigDataProvincesResp = new SmsStudentDataStatisticsBigDataProvincesResp();
            studentDataStatisticsBigDataProvincesResp.setStuProvinces(smsStudentDataStatisticsBigDataProvincesResp.getStuProvinces());
            studentDataStatisticsBigDataProvincesResp.setBoyNum(boyNum);
            studentDataStatisticsBigDataProvincesResp.setGirlNum(girlNum);
            studentDataStatisticsBigDataProvincesResp.setProvincesNum(provincesNum);
            provincesList.add(studentDataStatisticsBigDataProvincesResp);
        }
        return CommonResult.success(provincesList,(int)page.getTotal());
    }

}
